
//
// 120309 - AH - (Huset) Created.
// 120310 - AH - (Peppes, Nesttun *) Done for first Laetitia spec.
// 120312 - AH - (Garage) Done for second Laetitia spec.
// 120313 - AH - Made Serializable.
// 120314 - AH - (Hector) testData.
// 120317 - AH - (Bergen Off. Bibliotek *) status property.
// 120416 - AH - (Huset *) Missing property ChatOutputSerializable! 
// 120407 - AH - (Midtun) Commented away mock response.
// 1204
//

package org.soekrat.server.serialization;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

/**
 * <p>
 *   Data that is a Soekrat response to a visitor's request suitable for 
 *   server client protocol serialization (for example using JSON).
 * </p>
 * @author Arne Halvorsen (AH)
 * @author Laetitia Le Chatton (LLC)
 */
public final class SoekratChatResponseSerializable implements Serializable
{
  private static final long serialVersionUID = 3551783973421889311L;

  private String status="ok";
  
  private List<Serializable> testData=null;

  private String soekratResponseType="eventCE";
  
  @SuppressWarnings("unused")
  private PassingStrategySerializable passingStrategy;
  
  private VisitorAccountSerializable account=null;
  
  private ConversationElementSerializable ce=null;
  
  private ChatOutputSerializable output=null;
  
  /**
   * <p>
   *   Constructor.
   * </p>
   */
  public SoekratChatResponseSerializable(){}
  
  /**
   * <p>
   *   Adds test data.
   * </p>
   * @param td Test data.
   * @return {@code this}.
   */
  public SoekratChatResponseSerializable addTestData(Serializable td)
  {
    if (td==null)
    {
      throw new NullPointerException("td");  
    }
    
    if (testData==null) testData=new ArrayList<Serializable>();
    testData.add(td);
    return this;
  }
  
  /**
   * <p>
   *   Sets status message.
   * </p>
   * @param msg Status message. Anything but "ok" (the default) is an error
   *            message.
   * @return {@code this}.
   */
  public SoekratChatResponseSerializable status(String msg)
  {
    if (msg==null)
    {
      throw new NullPointerException("msg");
    }
    
    status=msg;
    
    return this;
  }
  
  /**
   * <p>
   *   Sets representative for passing strategy used.
   * </p>
   * @param ps {@link PassingStrategySerializable}.
   * @return {@code this}.
   */
  public SoekratChatResponseSerializable passingStrategy(
    PassingStrategySerializable ps)
  {
    if (ps==null)
    {
      throw new NullPointerException("ps");
    }
    
    this.passingStrategy=ps;
    return this;
  }
  
  /**
   * <p>
   *   Gets status message.
   * </p>
   * @return Status message.
   */
  public String status(){ return status; }
  
  /**
   * <p>
   *   Sets 
   *   {@link ChatOutputSerializable}.
   * </p>
   * @param output {@link ChatOutputSerializable} to set or {@code null} if to
   *               clear.
   * @return {@code this}.
   */
  public SoekratChatResponseSerializable chatOutput(
    ChatOutputSerializable output)
  {
    this.output=output;
    return this;
  }
  
  /**
   * <p>
   *   Gets 
   *   {@link ChatOutputSerializable}.
   * </p>
   * @return {@link ChatOutputSerializable} or {@code null} does not have.
   */
  public ChatOutputSerializable chatOutput(){ return this.output; }
  
  private final static Object[] E_OBJECT_A=new Object[0];
  
  /**
   * <p>
   *   Gets test data.
   * </p>
   * @return Test data.
   */
  public Object[] getTestData()
  {
    return testData==null ? E_OBJECT_A : testData.toArray(E_OBJECT_A);
  }
  
  /**
   * <p>
   *   Constructor.
   * </p>
   * @param soekratResponse Name on response kind, default is "eventCE". 
   */
  public SoekratChatResponseSerializable(String soekratResponseType)
  {
    if (soekratResponseType==null)
    {
      throw new NullPointerException("soekratResponseType");
    }
    
    this.soekratResponseType=soekratResponseType;
  }
  
  /**
   * <p>
   *   Gets name on response kind, default is "ChatOutput".
   * </p>
   * @return Name.
   */
  public String soekratResponseType(){ return soekratResponseType; }
  
  /**
   * <p>
   *   Sets 
   *   {@link VisitorAccountSerializable}.
   * </p>
   * @param v {@link VisitorAccountSerializable}.
   * @return {@code this}.
   */
  public SoekratChatResponseSerializable account(VisitorAccountSerializable v)
  { 
    account=v; 
    return this; 
  }
  
  /**
   * <p>
   *   Gets 
   *   {@link VisitorAccountSerializable}.
   * </p>
   * @return {@code Account} {@code null} if does not have.
   */
  public VisitorAccountSerializable account(){ return account; }
  
  /**
   * <p>
   *   Sets 
   *   {@link ConversationElementSerializable}.
   * </p>
   * @param v {@code CE} to set.
   * @return {@code this}.
   */
  public SoekratChatResponseSerializable ce(ConversationElementSerializable v)
  { 
    this.ce=v; 
    return this; 
  }
  
  /**
   * <p>
   *   Gets
   *   {@link ConversationElementSerializable}.
   * </p>
   * @return {@code CE}.
   */
  public ConversationElementSerializable ce(){ return ce; }
  
  /**
   * <p>
   *   Gets JSON code for {@code this}.
   * </p>
   * @return JSON code.
   */
  public String toJson()
  {
    return new GsonBuilder().setPrettyPrinting().create().toJson(this);
  }
  
  @Override
  public String toString(){ return new Gson().toJson(this); }
  
}
